package com.test.template.publish.using.elecbook.test;

import com.elecbook.content.model.po.Contribute;
import com.test.template.publish.config.fac.*;
import com.test.template.publish.config.manager.VelocityConfigManager;
import com.test.template.publish.config.util.data.TemplateInputOutputConfig;
import com.test.template.publish.config.util.data.VelocityContextUseInfo;
import com.test.template.tool.Tool;
import com.test.template.tool.VelocityConfig;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.junit.Test;

import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class ContributeETC_Manager {

    /**
     * 测试测试manager读取配置文件效果
     */
    @Test
    public void testManager() {
        VelocityConfigManager vcManager = vcManager();
        vcManager.readConfigFile();
        System.out.println(vcManager.getIoFileMap());
    }


    /**
     * 获取一个manager,暂时为不规范写法
     * // TODO 修复manager
     *
     * @return
     */
    VelocityConfigManager vcManager() {
        return VelocityConfigManager.builder()
                .tableName("contribute")
                .clazzPo(Contribute.class)
                .controllerPrefix("/content/contribute")
                .controllerPackage("com.elecbook.content.api")
                .servicePackageName("com.elecbook.content.service")
                .jsEntityPath("@/model/")
                .jsApiPath("@/api/content/contribute/contribute.js")
                .baseTemplateDirectory("publish-manager-v2")
                .build();
    }

    // 批量生成,核心函数
    @Test
    public void testAllGenerate() {
        VelocityConfigManager vcManager = vcManager();
        vcManager.readConfigFile();

        // 输出配置信息--倒时候可以设置到manager内
        String outputBaseDirectory = "src/test/output/test/";
        // 开始
        VelocityEngine velocityEngine = VelocityConfig.getVelocityEngine();
        // 获取context配置,批量获取配置
        VelocityContextUseInfo pack = getVelocityContext(vcManager);
        VelocityContext context = pack.getContext();
        // 为context设置工具tool
        context.put("tool", new Tool());
        // 批量输出
        for (TemplateInputOutputConfig ioConfig : pack.getIoList()) {
            System.out.println(ioConfig);

            // 加载模板
            Template template = velocityEngine.getTemplate(ioConfig.getTemplateFilePath());
            // 渲染模板
            StringWriter writer = new StringWriter();
            template.merge(context, writer);

            //输出结果
            String gFilePath = outputBaseDirectory + ioConfig.getOutputFileNames();
            VelocityConfig.output(writer, gFilePath);
            log.info("生成文件：{}",gFilePath);
        }
    }


    /**
     * 获取context
     *
     * @param vcManager
     */
    public VelocityContextUseInfo getVelocityContext(VelocityConfigManager vcManager) {
        //使用的模板文件信息 --废弃
        List<TemplateInputOutputConfig> ioList = new ArrayList<>();
        // 输出目录信息
        List<VelocityTemplateConfig> configs = new ArrayList<>();
        // 设置上下文变量
        VelocityContext context = new VelocityContext();
        // 根据配置了的工厂数目进行获取使用配置
        vcManager.getFactoryList().forEach(factory -> {
            try {
                log.debug("{}开始获取", factory.getName());
                Method method = factory.getDeclaredMethod("getInstance");
                // 调用静态方法,获取工厂实例
                Object instance = method.invoke(vcManager.getTableName());
                if (instance instanceof VelocityTemplateConfigFactory) {
//                    System.out.println("单例获取成功");
                    // 获取配置
                    VelocityTemplateConfig config = ((VelocityTemplateConfigFactory<?>) instance).getConfig(vcManager.getTableName());
                    System.out.println(config);
                    // 加入配置
                    addVelocityContextConfig(context, config);
                    // 加入输出路径
                    String gFileName = config.getFileName();
                    configs.add(config);
                    TemplateInputOutputConfig io = new TemplateInputOutputConfig();
                    io.setTemplateFilePath(vcManager.getIoFileMap().get(factory));
                    io.setOutputFileNames(gFileName);
                    ioList.add(io);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

        // 封装返回
        VelocityContextUseInfo pack = new VelocityContextUseInfo();
        pack.setContext(context);
        pack.setConfigs(configs);
        pack.setIoList(ioList);
        return pack;
    }

    /**
     * 添加配置，
     * 默认配置名称为类型名称
     * 比如
     * apiConfig ： object
     *
     * @param context
     * @param config
     */
    public void addVelocityContextConfig(VelocityContext context, VelocityTemplateConfig config) {
        String classTypeName = Tool.subStringAfterLastPunctuation(config.getClass().getTypeName(), ".");
        String lower1ClassName = Tool.toLowerCase(classTypeName, 1);
        context.put(lower1ClassName, config);
    }
}
